package com.boot.contorller;

import lombok.AllArgsConstructor;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collections;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("order")
@AllArgsConstructor
public class IndexController {
    private RedisTemplate<String, Object> redisTemplate;
    private Redisson redisson;

    @GetMapping("deduct")
    public String deductStock() {
        String lockKey = "lock:product_1";
        String clientId = UUID.randomUUID().toString();
        Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey, clientId, 10, TimeUnit.SECONDS);
        if (Boolean.FALSE.equals(result)) {
            return "系统繁忙";
        }
        int stock = 0;
        try {
            stock = Integer.parseInt(redisTemplate.opsForValue().get("stock").toString());
            if (stock > 0) {
                int realStock = stock - 1;
                redisTemplate.opsForValue().set("stock", realStock);
                System.out.println("扣减成功，剩余库存：" + realStock);
            } else {
                System.out.println("扣减失败，库存不足");
            }
        } catch (NumberFormatException e) {
            throw new RuntimeException(e);
        } finally {
            String lua =
                    "if redis.call('get', KEYS[1]) == ARGV[1] then " +
                            "return redis.call('del', KEYS[1]) " +
                            "else " +
                            "return 0 " +
                            "end";
            redisTemplate.execute(
                    new DefaultRedisScript<>(lua, Long.class),
                    Collections.singletonList(lockKey),
                    clientId
            );
        }
        return "end";
    }

    @GetMapping("deduct2")
    public String deductStock2() {
        String lockKey = "lock:product_1";
        RLock redissonLock = redisson.getLock(lockKey);
        redissonLock.lock();
        int stock = 0;
        try {
            stock = Integer.parseInt(redisTemplate.opsForValue().get("stock").toString());
            if (stock > 0) {
                stock = stock - 1;
                redisTemplate.opsForValue().set("stock", stock);
                return "扣减成功，剩余库存：" + stock;
            }
            return "库存不足";
        } finally {
            redissonLock.unlock();
        }
    }
}
